Cookie & Session & Token

Cookie & Session & Token

之前在学习缓存和身份验证的时候,无意间扰乱了自己对于Cookie & Session & Token三者的一些概念上的理解,所以写下此文,便于梳理自己的知识结构和分清三者的区别。


首先,cookie & session都是当下最流行的会话跟踪技术,由于HTTP是一种无状态的连接协议,服务器单单从网络连接中并不能确认客户端的用户身份和用户状态,所以为了实现这个需求,便出现了cooike & session的会话跟踪机制。

一、Cookie

Cookie实际上是一小段的文本信息(文本文件)。

客户端请求服务器,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。客户端浏览器会把Cookie保存起来。当浏览器再请求该网站时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器检查该Cookie,以此来辨认用户状态。此外,服务器还可以根据需要修改Cookie的内容。(cooike存放在客户端中,在请求时放在了req-header中,以便服务端确认)




二、Session

session是另一种记录客户状态的机制,不同的是cookie保存在客户端浏览器中,而session保存在服务器上。

客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,这就是session。客户端浏览器再次访问时只需要从该session中查找该客户的状态就可以了。

同时我们也看到,由于采用服务器端保持状态的方案在客户端也需要保存一个标识,(不然因为HTTP的无状态性,服务端无法识别客户端的用户身份),所以在使用session机制的时候也需要借助于cookie机制或者URL重写(如果客户端Cookie禁用)来达到保存标识的目的。

所以一般来说,当使用session时,服务器向客户端浏览器发送一个名为JSESSIONID的Cookie,它的值为该Session的id,Session依据该Cookie来识别是否为同一用户。

而URL地址重写的原理是将该用户Session的id信息重写到URL地址中。服务器能够解析重写后的URL获取Session的id。




Cookie和Session的区别?
  • Cookie是存在客户端,Session存在服务器,因为Session不会在网络上运输,而Cookie存储在本地,所以Session的安全性更高一点。

  • Cookie如果不设置时间,当关闭浏览器时,Cookie就失效,不会在本地保存;Session的生命周期是一个会话(当启动浏览器到关闭浏览器)

  • 在存储相对持久的信息时,应考虑使用 Cookie,因为 Cookie 可以以文件的形式,存储在客户端。在进行一些登录的验证及信息拦截的时候,可以使用 Session。


三、注意

  • 现在大多都是Session + Cookie,但是只用session不用cookie,或是只用cookie,不用session在理论上都可以保持会话状态。可是实际中因为多种原因,一般不会单独使用
  • 用session只需要在客户端保存一个id,实际上大量数据都是保存在服务端。如果全部用cookie,数据量大的时候客户端是没有那么多空间的。
  • 如果只用cookie不用session,那么账户信息全部保存在客户端,一旦被劫持,全部信息都会泄露。并且客户端数据量变大,网络传输的数据量也会变大




四、Cookie & Session的安全问题

在使用Cookie & Session机制来进行客户端身份验证的时候,遭受CSRF攻击便成为了一个需要解决的问题。

那么,什么是CSRF攻击?

Pandao editor.md

面对CSRF攻击,主要的防御措施有:

  • 检查referer字段。HTTP头中有一个Referer字段,这个字段是用来标明请求来源于哪一个网址。通常来说,Referer字段应和请求的地址是在同一个域名下的。服务器可以通过判断Referer字段来判断请求的来源。 这种方法简单易行,但也有其局限性。http协议无法保证来访的浏览器的具体实现,可以通过篡改Referer字段的方式来进行攻击。
  • 使用token


五、Token

Token是什么?

使用token机制的身份验证方法,在服务器端不需要存储用户的登录记录。大概的流程:

  • 客户端使用用户名和密码请求登录。服务端收到请求,验证用户名和密码。
  • 验证成功后,服务端会生成一个token,然后把这个token发送给客户端。
  • 客户端收到token后把它存储起来,可以放在cookie或者Local Storage(本地存储)里。
  • 客户端每次向服务端发送请求的时候都需要带上服务端发给的token。
  • 服务端收到请求,然后去验证客户端请求里面带着token,如果验证成功,就向客户端返回请求的数据。
Token为什么可以抵御CSRF攻击?

CSRF 攻击之所以能够成功,是因为黑客可以完全伪造用户的请求,该请求中所有的用户验证信息都是存在于 cookie 中,因此黑客可以在不知道这些验证信息的情况下直接利用用户自己的 cookie 来通过安全验证。要抵御 CSRF,关键在于在请求中放入黑客所不能伪造的信息,并且该信息不存在于 cookie 之中。可以在 HTTP 请求中以参数的形式加入一个随机产生的 token,并在服务器端建立一个拦截器来验证这个 token,如果请求中没有 token 或者 token 内容不正确,则认为可能是 CSRF 攻击而拒绝该请求。

Token机制和Session机制的区别?

看起来session的验证和token的验证很相似,都是从服务器返回一个数据,然后之后每次请求的时候都带着,发送给服务器验证。但其实是有很大不同的。

  • session的session_id只是一个唯一标识的字符串,本身不存放任何信息,需要通过这个session_id来找到session,session才存放了相应的信息,其中包括用户的登陆状态,就算没有请求登陆或者登陆没有成功,依然会有session和session_id。而token本身就是在登陆成功后才会签发并返回的,而且token是一些参数和随机数按照某种规则生成的字符串,其中一个参数就是用户的信息,也就是说token本身就存放了用户的相关信息。我们只需要在服务器验证这个token是否是合法的就可以了。

  • session的使用需要配合cookie,我们知道只有浏览器才会去解析请求响应头里面的cookie。但现在经常会出现前后端分离的写法,通常都是后端提供接口,前端我们的客户端不止是浏览器,还有APP等其他客户端。这个时候cookie是不起作用的。但是token就没有这些问题,token可以被APP存放在内存当中,本身不局限于浏览器。也就是说token有更广的适用性